﻿using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using UnityEngine;
using System;

namespace Utility.DataStructure
{
	public class ReadOnlySet<T> : IReadOnlyCollection<T>, ISet<T>
	{
		public static ReadOnlySet<T> Empty { get; } = new ReadOnlySet<T> (new HashSet<T> ());

		ISet<T> set;

		public ReadOnlySet (ISet<T> set)
		{
			this.set = set;
		}

		public int Count => set.Count;

		public bool IsReadOnly => true;

		public bool Contains (T item)
		{
			return set.Contains (item);
		}

		public void CopyTo (T[] array, int arrayIndex)
		{
			set.CopyTo (array, arrayIndex);
		}

		public IEnumerator<T> GetEnumerator ()
		{
			return set.GetEnumerator ();
		}

		public bool IsProperSubsetOf (IEnumerable<T> other)
		{
			return set.IsProperSubsetOf (other);
		}

		public bool IsProperSupersetOf (IEnumerable<T> other)
		{
			return set.IsProperSupersetOf (other);
		}

		public bool IsSubsetOf (IEnumerable<T> other)
		{
			return set.IsSubsetOf (other);
		}

		public bool IsSupersetOf (IEnumerable<T> other)
		{
			return set.IsSupersetOf (other);
		}

		public bool Overlaps (IEnumerable<T> other)
		{
			return set.Overlaps (other);
		}

		public bool Remove (T item)
		{
			return set.Remove (item);
		}

		public bool SetEquals (IEnumerable<T> other)
		{
			return set.SetEquals (other);
		}



		#region implicit iterface
		bool ISet<T>.Add (T item)
		{
			throw new NotSupportedException ();
		}

		void ICollection<T>.Clear ()
		{
			throw new NotSupportedException ();
		}

		void ISet<T>.ExceptWith (IEnumerable<T> other)
		{
			throw new NotSupportedException ();
		}
		void ISet<T>.IntersectWith (IEnumerable<T> other)
		{
			throw new NotSupportedException ();
		}
		void ISet<T>.SymmetricExceptWith (IEnumerable<T> other)
		{
			throw new NotSupportedException ();
		}

		void ISet<T>.UnionWith (IEnumerable<T> other)
		{
			throw new NotSupportedException ();
		}

		void ICollection<T>.Add (T item)
		{
			throw new NotSupportedException ();
		}

		IEnumerator IEnumerable.GetEnumerator ()
		{
			return set.GetEnumerator ();
		}
		#endregion
	}
}